package com.ict.ms.trackPlayBack.service.api.impl;

import com.ict.ms.trackPlayBack.service.dao.IHistoryServiceDao;
import com.ict.ms.trackPlayBack.facade.dto.AreaParams;
import com.ict.ms.trackPlayBack.facade.dto.Circular;
import com.ict.ms.trackPlayBack.facade.dto.CircularSector;
import com.ict.ms.trackPlayBack.facade.dto.ResultObjWithCount;
import com.ict.ms.trackPlayBack.facade.model.Analysis;
import com.ict.ms.trackPlayBack.facade.model.ListShipDataReturn;
import com.ict.ms.trackPlayBack.facade.model.MmsiIOCountWithStaticInfo;
import com.ict.ms.trackPlayBack.facade.model.ShipDataReturn;
import com.ict.ms.trackPlayBack.facade.api.IHistoryAnalysisService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("historyAnalysisService")
public class HistoryAnalysisService implements IHistoryAnalysisService{
    @Resource
    IHistoryServiceDao iHistoryServiceDao;

    /**
     * 区域流量分析
     * @param areaParams
     * @return
     */
    public ResultObjWithCount getAnalysis(AreaParams areaParams,int mode){
        ResultObjWithCount resultObj=new ResultObjWithCount();
        try{
            List<Analysis> analysisList;
            String msi;
            //新建不同目标为key，该目标轨迹点为Value的Map
            Map<String,ArrayList<Analysis>> map2=new HashMap<String,ArrayList<Analysis>>();

            com.ict.ms.trackPlayBack.facade.common.PrintUtile.printMode(mode);
            //mode;0:综合模式；1：原始模式
            if(mode==0){
                analysisList=iHistoryServiceDao.getFuseAnalysis(areaParams);
                for(int i=0;i<analysisList.size();i++){
                    msi=analysisList.get(i).getMsi()+"";
                    Analysis analysis=analysisList.get(i);
                    //==================1.对指定时间段内点的轨迹进行按不同目标列表分类
                    putAddAnalysis(map2,msi,analysis);
                }
            }else{
                analysisList=iHistoryServiceDao.getOrigAnalysis(areaParams);
                for(int i=0;i<analysisList.size();i++){
                    msi=analysisList.get(i).getMsi()+"";
                    Analysis analysis=analysisList.get(i);
                    //==================1.对指定时间段内点的轨迹进行按不同目标列表分类
                    putOrigAddAnalysis(map2,msi,analysis);
                }
            }

            //新建包括每个目标进出次数对象的列表
            List<MmsiIOCountWithStaticInfo> mmsiIOCountWithStaticInfoList=new ArrayList<MmsiIOCountWithStaticInfo>();
            //==================2.对分类的目标列表进行进出次数计算
            for(Map.Entry<String,ArrayList<Analysis>> entry:map2.entrySet()){
//                此处不需要key，如果需要，原始模式需要拆分
//                Integer.parseInt(entry.getKey());

                com.ict.ms.trackPlayBack.facade.common.PrintUtile.printSingleShipKey(entry.getKey());

                List<Analysis> analysisList1=entry.getValue();
                MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo=IOAnalysis(analysisList1,areaParams);
                mmsiIOCountWithStaticInfoList.add(mmsiIOCountWithStaticInfo);
            }

            //对进出目标次数进行分类和总数叠加计算
            String countryKey;
            int countDstSum=0;//驶入总次数
            int countSrcSum=0;//驶出总次数

            //新建返回对象，包括驶入总此时、驶出总次数、各个国家各种类型驶入列表、各个国家各种类型驶出列表
            ListShipDataReturn listShipDataReturn=new ListShipDataReturn();

            Map<String,ShipDataReturn> mapDst=new HashMap<String, ShipDataReturn>();//不同国家不同类型驶入次数记录Map，国家为Key，各类型进出次数对象为Value
            Map<String,ShipDataReturn> mapSrc=new HashMap<String, ShipDataReturn>();//不同国家不同类型驶出次数记录Map，国家为Key，各类型进出次数对象为Value
            for(int j=0;j<mmsiIOCountWithStaticInfoList.size();j++){
                //获取国家，作为Map的key
                countryKey=mmsiIOCountWithStaticInfoList.get(j).getCou();

                /**
                 货船 ：1
                 油轮： 3
                 拖船 ：6
                 拖轮 ：4
                 搜救船 ：2
                 客船 ：7
                 渔船：5
                 军事船：8
                 */

                countDstSum=countDstSum+mmsiIOCountWithStaticInfoList.get(j).getDstSum();
                countSrcSum=countSrcSum+mmsiIOCountWithStaticInfoList.get(j).getSrcSum();

                shipIOAnalysis(mapDst,mapSrc,countryKey,mmsiIOCountWithStaticInfoList.get(j));
            }

            //从Map中获取不同国家，指定类型船的驶入列表
            List<ShipDataReturn> shipDst=new ArrayList<ShipDataReturn>();
            for(Map.Entry<String,ShipDataReturn> entryDst:mapDst.entrySet()){
                shipDst.add(entryDst.getValue());
            }

            //从Map中获取不同国家，指定类型船的驶出列表
            List<ShipDataReturn> shipSrc=new ArrayList<ShipDataReturn>();
            for(Map.Entry<String,ShipDataReturn> entrySrc:mapSrc.entrySet()){
                shipSrc.add(entrySrc.getValue());
            }

            //添加到总List
            listShipDataReturn.setSrcSum(countSrcSum);
            listShipDataReturn.setDstSum(countDstSum);
            listShipDataReturn.setShipDst(shipDst);
            listShipDataReturn.setShipSrc(shipSrc);

            resultObj.setState(1);
            resultObj.setObj(listShipDataReturn);
            return resultObj;
        }catch (Exception e){
            resultObj.setState(-1);
            System.out.println("数据库操作失败："+e);
            return resultObj;
        }
    }

    /**
     * 扇（环）形区域态势回放
     * @param mode
     * @param hisAreaParams
     * @param circularSector
     * @return
     */
    public ResultObjWithCount analysisSector(int mode,AreaParams hisAreaParams,CircularSector circularSector){
        ResultObjWithCount resultObj=new ResultObjWithCount();
        try{
            List<Analysis> analysisList;
            String msi;
            //新建不同目标为key，该目标轨迹点为Value的Map
            Map<String,ArrayList<Analysis>> map2=new HashMap<String,ArrayList<Analysis>>();

            //mode;0:综合模式；1：原始模式
            if(mode==0){
                analysisList=iHistoryServiceDao.getFuseAnalysis(hisAreaParams);
                for(int i=0;i<analysisList.size();i++){
                    msi=analysisList.get(i).getMsi()+"";
                    Analysis analysis=analysisList.get(i);
                    //==================1.对指定时间段内点的轨迹进行按不同目标列表分类
                    putAddAnalysis(map2,msi,analysis);
                }
            }else{
                analysisList=iHistoryServiceDao.getOrigAnalysis(hisAreaParams);
                for(int i=0;i<analysisList.size();i++){
                    msi=analysisList.get(i).getMsi()+"";
                    Analysis analysis=analysisList.get(i);
                    //==================1.对指定时间段内点的轨迹进行按不同目标列表分类
                    putOrigAddAnalysis(map2,msi,analysis);
                }
            }

            //新建包括每个目标进出次数对象的列表
            List<MmsiIOCountWithStaticInfo> mmsiIOCountWithStaticInfoList=new ArrayList<MmsiIOCountWithStaticInfo>();
            //==================2.对分类的目标列表进行进出次数计算
            for(Map.Entry<String,ArrayList<Analysis>> entry:map2.entrySet()){
//                此处不需要key，如果需要，原始模式需要拆分
//                Integer.parseInt(entry.getKey());
                List<Analysis> analysisList1=entry.getValue();

                MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo;
                if (circularSector.getRidius()==circularSector.getRidsaml()||circularSector.getRidsaml()==-1){
                    com.ict.ms.trackPlayBack.facade.common.CircularSectorWithLongitudeCrossed180 cir1=new com.ict.ms.trackPlayBack.facade.common.CircularSectorWithLongitudeCrossed180(circularSector.getCirlon(),circularSector.getCirlat(),circularSector.getRidius(),circularSector.getStartDeg(),circularSector.getEndDeg());
                    mmsiIOCountWithStaticInfo=IOAnalysisSector(analysisList1,cir1);
                }else {
                    com.ict.ms.trackPlayBack.facade.common.AnnularSectorWithLongitudeCrossed180 cir2=new com.ict.ms.trackPlayBack.facade.common.AnnularSectorWithLongitudeCrossed180(circularSector.getCirlon(),circularSector.getCirlat(),circularSector.getRidius(),circularSector.getStartDeg(),circularSector.getEndDeg(),circularSector.getRidsaml());
                    mmsiIOCountWithStaticInfo=IOAnalysisSectorAnnular(analysisList1,cir2);
                }

                mmsiIOCountWithStaticInfoList.add(mmsiIOCountWithStaticInfo);
            }

            //对进出目标次数进行分类和总数叠加计算
            String countryKey;
            int countDstSum=0;//驶入总次数
            int countSrcSum=0;//驶出总次数

            //新建返回对象，包括驶入总此时、驶出总次数、各个国家各种类型驶入列表、各个国家各种类型驶出列表
            ListShipDataReturn listShipDataReturn=new ListShipDataReturn();

            Map<String,ShipDataReturn> mapDst=new HashMap<String, ShipDataReturn>();//不同国家不同类型驶入次数记录Map，国家为Key，各类型进出次数对象为Value
            Map<String,ShipDataReturn> mapSrc=new HashMap<String, ShipDataReturn>();//不同国家不同类型驶出次数记录Map，国家为Key，各类型进出次数对象为Value
            for(int j=0;j<mmsiIOCountWithStaticInfoList.size();j++){
                //获取国家，作为Map的key
                countryKey=mmsiIOCountWithStaticInfoList.get(j).getCou();

                /**
                 货船 ：1
                 油轮： 3
                 拖船 ：6
                 拖轮 ：4
                 搜救船 ：2
                 客船 ：7
                 渔船：5
                 军事船：8
                 */

                countDstSum=countDstSum+mmsiIOCountWithStaticInfoList.get(j).getDstSum();
                countSrcSum=countSrcSum+mmsiIOCountWithStaticInfoList.get(j).getSrcSum();

                shipIOAnalysis(mapDst,mapSrc,countryKey,mmsiIOCountWithStaticInfoList.get(j));
            }

            //从Map中获取不同国家，指定类型船的驶入列表
            List<ShipDataReturn> shipDst=new ArrayList<ShipDataReturn>();
            for(Map.Entry<String,ShipDataReturn> entryDst:mapDst.entrySet()){
                shipDst.add(entryDst.getValue());
            }

            //从Map中获取不同国家，指定类型船的驶出列表
            List<ShipDataReturn> shipSrc=new ArrayList<ShipDataReturn>();
            for(Map.Entry<String,ShipDataReturn> entrySrc:mapSrc.entrySet()){
                shipSrc.add(entrySrc.getValue());
            }

            //添加到总List
            listShipDataReturn.setSrcSum(countSrcSum);
            listShipDataReturn.setDstSum(countDstSum);
            listShipDataReturn.setShipDst(shipDst);
            listShipDataReturn.setShipSrc(shipSrc);

            resultObj.setState(1);
            resultObj.setObj(listShipDataReturn);
            return resultObj;
        }catch (Exception e){
            resultObj.setState(-1);
            System.out.println("数据库操作失败："+e);
            return resultObj;
        }
    }

    /**
     * 圆形区域流量分析
     * @param mode
     * @param areaParams
     * @param circular
     * @return
     */
    public ResultObjWithCount getAnalysisCirCular(int mode,AreaParams areaParams, Circular circular){
        ResultObjWithCount resultObj=new ResultObjWithCount();
        try{
            List<Analysis> analysisList;
            String msi;
            //新建不同目标为key，该目标轨迹点为Value的Map
            Map<String,ArrayList<Analysis>> map2=new HashMap<String,ArrayList<Analysis>>();

            //mode;0:综合模式；1：原始模式
            if(mode==0){
                analysisList=iHistoryServiceDao.getFuseAnalysis(areaParams);
                for(int i=0;i<analysisList.size();i++){
                    msi=analysisList.get(i).getMsi()+"";
                    Analysis analysis=analysisList.get(i);
                    //==================1.对指定时间段内点的轨迹进行按不同目标列表分类
                    putAddAnalysis(map2,msi,analysis);
                }
            }else{
                analysisList=iHistoryServiceDao.getOrigAnalysis(areaParams);
                for(int i=0;i<analysisList.size();i++){
                    msi=analysisList.get(i).getMsi()+"";
                    Analysis analysis=analysisList.get(i);
                    //==================1.对指定时间段内点的轨迹进行按不同目标列表分类
                    putOrigAddAnalysis(map2,msi,analysis);
                }
            }

            //新建包括每个目标进出次数对象的列表
            List<MmsiIOCountWithStaticInfo> mmsiIOCountWithStaticInfoList=new ArrayList<MmsiIOCountWithStaticInfo>();
            //==================2.对分类的目标列表进行进出次数计算
            for(Map.Entry<String,ArrayList<Analysis>> entry:map2.entrySet()){
//                此处不需要key，如果需要，原始模式需要拆分
//                Integer.parseInt(entry.getKey());
                List<Analysis> analysisList1=entry.getValue();
                MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo=IOAnalysisCirCular(analysisList1,circular);
                mmsiIOCountWithStaticInfoList.add(mmsiIOCountWithStaticInfo);
            }

            //对进出目标次数进行分类和总数叠加计算
            String countryKey;
            int countDstSum=0;//驶入总次数
            int countSrcSum=0;//驶出总次数

            //新建返回对象，包括驶入总此时、驶出总次数、各个国家各种类型驶入列表、各个国家各种类型驶出列表
            ListShipDataReturn listShipDataReturn=new ListShipDataReturn();

            Map<String,ShipDataReturn> mapDst=new HashMap<String, ShipDataReturn>();//不同国家不同类型驶入次数记录Map，国家为Key，各类型进出次数对象为Value
            Map<String,ShipDataReturn> mapSrc=new HashMap<String, ShipDataReturn>();//不同国家不同类型驶出次数记录Map，国家为Key，各类型进出次数对象为Value
            for(int j=0;j<mmsiIOCountWithStaticInfoList.size();j++){
                //获取国家，作为Map的key
                countryKey=mmsiIOCountWithStaticInfoList.get(j).getCou();

                /**
                 货船 ：1
                 油轮： 3
                 拖船 ：6
                 拖轮 ：4
                 搜救船 ：2
                 客船 ：7
                 渔船：5
                 军事船：8
                 */

                countDstSum=countDstSum+mmsiIOCountWithStaticInfoList.get(j).getDstSum();
                countSrcSum=countSrcSum+mmsiIOCountWithStaticInfoList.get(j).getSrcSum();

                shipIOAnalysis(mapDst,mapSrc,countryKey,mmsiIOCountWithStaticInfoList.get(j));
            }

            //从Map中获取不同国家，指定类型船的驶入列表
            List<ShipDataReturn> shipDst=new ArrayList<ShipDataReturn>();
            for(Map.Entry<String,ShipDataReturn> entryDst:mapDst.entrySet()){
                shipDst.add(entryDst.getValue());
            }

            //从Map中获取不同国家，指定类型船的驶出列表
            List<ShipDataReturn> shipSrc=new ArrayList<ShipDataReturn>();
            for(Map.Entry<String,ShipDataReturn> entrySrc:mapSrc.entrySet()){
                shipSrc.add(entrySrc.getValue());
            }

            //添加到总List
            listShipDataReturn.setSrcSum(countSrcSum);
            listShipDataReturn.setDstSum(countDstSum);
            listShipDataReturn.setShipDst(shipDst);
            listShipDataReturn.setShipSrc(shipSrc);

            resultObj.setState(1);
            resultObj.setObj(listShipDataReturn);
            return resultObj;
        }catch (Exception e){
            resultObj.setState(-1);
            System.out.println("数据库操作失败："+e);
            return resultObj;
        }
    }



    /**
     * 多边形区域流量分析
     * @param mode
     * @param areaParams
     * @param point_x_list
     * @param point_y_list
     * @return
     */
    public ResultObjWithCount getAnalysisPolygons(int mode,AreaParams areaParams, ArrayList<Double> point_x_list,ArrayList<Double> point_y_list){
        com.ict.ms.trackPlayBack.facade.common.PolygonWithLongitudeCrossed180 p = new com.ict.ms.trackPlayBack.facade.common.PolygonWithLongitudeCrossed180(point_x_list,point_y_list);

        ResultObjWithCount resultObj=new ResultObjWithCount();
        try{
            List<Analysis> analysisList;
            String msi;
            //新建不同目标为key，该目标轨迹点为Value的Map
            Map<String,ArrayList<Analysis>> map2=new HashMap<String,ArrayList<Analysis>>();

            //mode;0:综合模式；1：原始模式
            if(mode==0){
                analysisList=iHistoryServiceDao.getFuseAnalysis(areaParams);
                for(int i=0;i<analysisList.size();i++){
                    msi=analysisList.get(i).getMsi()+"";
                    Analysis analysis=analysisList.get(i);
                    //==================1.对指定时间段内点的轨迹进行按不同目标列表分类
                    putAddAnalysis(map2,msi,analysis);
                }
            }else{
                analysisList=iHistoryServiceDao.getOrigAnalysis(areaParams);
                for(int i=0;i<analysisList.size();i++){
                    msi=analysisList.get(i).getMsi()+"";
                    Analysis analysis=analysisList.get(i);
                    //==================1.对指定时间段内点的轨迹进行按不同目标列表分类
                    putOrigAddAnalysis(map2,msi,analysis);
                }
            }

            //新建包括每个目标进出次数对象的列表
            List<MmsiIOCountWithStaticInfo> mmsiIOCountWithStaticInfoList=new ArrayList<MmsiIOCountWithStaticInfo>();
            //==================2.对分类的目标列表进行进出次数计算
            for(Map.Entry<String,ArrayList<Analysis>> entry:map2.entrySet()){
//                此处不需要key，如果需要，原始模式需要拆分
//                Integer.parseInt(entry.getKey());
                List<Analysis> analysisList1=entry.getValue();
                MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo=IOAnalysisPolygons(analysisList1,p);
                mmsiIOCountWithStaticInfoList.add(mmsiIOCountWithStaticInfo);
            }

            //对进出目标次数进行分类和总数叠加计算
            String countryKey;
            int countDstSum=0;//驶入总次数
            int countSrcSum=0;//驶出总次数

            //新建返回对象，包括驶入总此时、驶出总次数、各个国家各种类型驶入列表、各个国家各种类型驶出列表
            ListShipDataReturn listShipDataReturn=new ListShipDataReturn();

            Map<String,ShipDataReturn> mapDst=new HashMap<String, ShipDataReturn>();//不同国家不同类型驶入次数记录Map，国家为Key，各类型进出次数对象为Value
            Map<String,ShipDataReturn> mapSrc=new HashMap<String, ShipDataReturn>();//不同国家不同类型驶出次数记录Map，国家为Key，各类型进出次数对象为Value
            for(int j=0;j<mmsiIOCountWithStaticInfoList.size();j++){
                //获取国家，作为Map的key
                countryKey=mmsiIOCountWithStaticInfoList.get(j).getCou();

                /**
                 货船 ：1
                 油轮： 3
                 拖船 ：6
                 拖轮 ：4
                 搜救船 ：2
                 客船 ：7
                 渔船：5
                 军事船：8
                 */

                countDstSum=countDstSum+mmsiIOCountWithStaticInfoList.get(j).getDstSum();
                countSrcSum=countSrcSum+mmsiIOCountWithStaticInfoList.get(j).getSrcSum();

                shipIOAnalysis(mapDst,mapSrc,countryKey,mmsiIOCountWithStaticInfoList.get(j));
            }

            //从Map中获取不同国家，指定类型船的驶入列表
            List<ShipDataReturn> shipDst=new ArrayList<ShipDataReturn>();
            for(Map.Entry<String,ShipDataReturn> entryDst:mapDst.entrySet()){
                shipDst.add(entryDst.getValue());
            }

            //从Map中获取不同国家，指定类型船的驶出列表
            List<ShipDataReturn> shipSrc=new ArrayList<ShipDataReturn>();
            for(Map.Entry<String,ShipDataReturn> entrySrc:mapSrc.entrySet()){
                shipSrc.add(entrySrc.getValue());
            }

            //添加到总List
            listShipDataReturn.setSrcSum(countSrcSum);
            listShipDataReturn.setDstSum(countDstSum);
            listShipDataReturn.setShipDst(shipDst);
            listShipDataReturn.setShipSrc(shipSrc);

            resultObj.setState(1);
            resultObj.setObj(listShipDataReturn);
            return resultObj;
        }catch (Exception e){
            resultObj.setState(-1);
            System.out.println("数据库操作失败："+e);
            return resultObj;
        }
    }

    /**
     * 对不同国家指定类型的船舶进出进行列表计算
     * @param mapDst 不同国家，不同船舶类型船舶驶入map
     * @param mapSrc 不同国家，不同船舶类型船舶驶出map
     * @param key 国家作为key，有则更新，无则新建并且更新
     * @param mmsiIOCountWithStaticInfo 船舶的进出次数对象，包括该船舶的静态信息
     */
    public void shipIOAnalysis(Map<String,ShipDataReturn> mapDst,Map<String,ShipDataReturn> mapSrc,String key,MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo){
        //驶入
        if(mmsiIOCountWithStaticInfo.getDstSum()>0){
            ShipDataReturn shipDataReturnDst;

            //国家作为key，有则更新，无则新建并且更新
            if(!mapDst.containsKey(key)){
                shipDataReturnDst=new ShipDataReturn();
                mapDst.put(key, shipDataReturnDst);
            }
            shipDataReturnDst=mapDst.get(key);

            //设置赋予国家属性给该对象
            shipDataReturnDst.setCountryCn(mmsiIOCountWithStaticInfo.getCou());

            //获取该船舶静态信息中的船舶类型,对该类型的进出次数属性进行追加
            switch (DealAisShipType(mmsiIOCountWithStaticInfo.getAst())){
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_HUOCHUAN:
                    shipDataReturnDst.setShiphuo(shipDataReturnDst.getShiphuo()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_YOULUN:
                    shipDataReturnDst.setShipyou(shipDataReturnDst.getShipyou()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_TUOCHUAN:
                    shipDataReturnDst.setShiptuo(shipDataReturnDst.getShiptuo()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_YUCHUAN:
                    shipDataReturnDst.setShipyu(shipDataReturnDst.getShipyu()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_KECHUAN:
                    shipDataReturnDst.setShipke(shipDataReturnDst.getShipke()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_TUOLUN:
                    shipDataReturnDst.setShiptl(shipDataReturnDst.getShiptl()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_SOUJIUCHUAN:
                    shipDataReturnDst.setShipsj(shipDataReturnDst.getShipsj()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_JUNSHICHUAN:
                    shipDataReturnDst.setShipjun(shipDataReturnDst.getShipjun()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
                default:
                    shipDataReturnDst.setShipother(shipDataReturnDst.getShipother()+mmsiIOCountWithStaticInfo.getDstSum());
                    break;
            }
        }

        //驶出
        if(mmsiIOCountWithStaticInfo.getSrcSum()>0){
            ShipDataReturn shipDataReturnSrc;

            //国家作为key，有则更新，无则新建并且更新
            if(!mapSrc.containsKey(key)){
                shipDataReturnSrc=new ShipDataReturn();
                mapSrc.put(key, shipDataReturnSrc);
            }
            shipDataReturnSrc=mapSrc.get(key);

            //设置赋予国家属性给该对象
            shipDataReturnSrc.setCountryCn(mmsiIOCountWithStaticInfo.getCou());

            //获取该船舶静态信息中的船舶类型,对该类型的进出次数属性进行追加
            switch (DealAisShipType(mmsiIOCountWithStaticInfo.getAst())){
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_HUOCHUAN:
                    shipDataReturnSrc.setShiphuo(shipDataReturnSrc.getShiphuo()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_YOULUN:
                    shipDataReturnSrc.setShipyou(shipDataReturnSrc.getShipyou()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_TUOCHUAN:
                    shipDataReturnSrc.setShiptuo(shipDataReturnSrc.getShiptuo()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_YUCHUAN:
                    shipDataReturnSrc.setShipyu(shipDataReturnSrc.getShipyu()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_KECHUAN:
                    shipDataReturnSrc.setShipke(shipDataReturnSrc.getShipke()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_TUOLUN:
                    shipDataReturnSrc.setShiptl(shipDataReturnSrc.getShiptl()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_SOUJIUCHUAN:
                    shipDataReturnSrc.setShipsj(shipDataReturnSrc.getShipsj()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
                case com.ict.ms.trackPlayBack.facade.common.ShipType.AIS_JUNSHICHUAN:
                    shipDataReturnSrc.setShipjun(shipDataReturnSrc.getShipjun()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
                default:
                    shipDataReturnSrc.setShipother(shipDataReturnSrc.getShipother()+mmsiIOCountWithStaticInfo.getSrcSum());
                    break;
            }
        }
    }

    //将需要进入循环的变量取出设置(节省内存)
    private int posLon=0;
    private int posLat=0;
    //标志,1：在区域内，-1：不在区域内
    private int flag;
    int inCount;//流入次数
    int outCount;//流出次数

    /**
     * 对每个目标轨迹列表进行进出量分析计算（矩形）
     * @param analysisList 目标轨迹列表
     * @param areaParams 区域参数对象
     * @return 返回每艘船的进出次数,包含该搜船的国家、类型、MMSI等静态信息
     */
    public MmsiIOCountWithStaticInfo IOAnalysis(List<Analysis> analysisList, AreaParams areaParams){
        inCount=0;//流入次数
        outCount=0;//流出次数
        flag=0;//1:在区域内；2：不在区域内

        MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo=new MmsiIOCountWithStaticInfo();
        for(int i=0;i<analysisList.size();i++){

            com.ict.ms.trackPlayBack.facade.common.PrintUtile.printSingleShipAnalysis(analysisList.get(i));

            posLon=analysisList.get(i).getLo();
            posLat=analysisList.get(i).getLa();
            //对其他每个点进行判断是否在指定区域内
            if(posLon>areaParams.getLdlon()&&posLon<areaParams.getUrlon()&&posLat>areaParams.getLdlat()&&posLat<areaParams.getUrlat())
            {
                //目标点在该区域，如果一开始不在该区域，那么记录驶入追加一次，并且状态设置为1（进入）
                if (flag==-1){
                    inCount=inCount+1;

                    com.ict.ms.trackPlayBack.facade.common.PrintUtile.printSingleShipIOOrNot(1);
                }else {
                    com.ict.ms.trackPlayBack.facade.common.PrintUtile.printSingleShipIOOrNot(0);
                }
                flag=1;
            }else {
                //目标点不在该区域，如果一开始在该区域，那么记录驶出追加一次，并且状态设置为-1（驶出）
                if (flag==1){
                    outCount=outCount+1;

                    com.ict.ms.trackPlayBack.facade.common.PrintUtile.printSingleShipIOOrNot(2);
                }else {
                    com.ict.ms.trackPlayBack.facade.common.PrintUtile.printSingleShipIOOrNot(0);
                }
                flag=-1;
            }
        }

        //船舶静态信息，国家名、船舶类型、MMSI
        mmsiIOCountWithStaticInfo.setAst(analysisList.get(0).getAst());
        mmsiIOCountWithStaticInfo.setCou(analysisList.get(0).getCou());
        mmsiIOCountWithStaticInfo.setMmsi(analysisList.get(0).getMsi());
        //将该搜船的进出信息存入该对象
        mmsiIOCountWithStaticInfo.setDstSum(inCount);
        mmsiIOCountWithStaticInfo.setSrcSum(outCount);
        return mmsiIOCountWithStaticInfo;
    }

    /**
     * 对每个目标轨迹列表进行进出量分析计算（圆形）
     * @param analysisList
     * @param circular
     * @return
     */
    public MmsiIOCountWithStaticInfo IOAnalysisCirCular(List<Analysis> analysisList,Circular circular){
        inCount=0;//流入次数
        outCount=0;//流出次数
        flag=0;//1:在区域内；2：不在区域内

        MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo=new MmsiIOCountWithStaticInfo();
        for(int i=0;i<analysisList.size();i++){
            posLon=analysisList.get(i).getLo();
            posLat=analysisList.get(i).getLa();
            //对其他每个点进行判断是否在指定区域内
            if(com.ict.ms.trackPlayBack.facade.common.IFInArea.ifInCircular(posLon,posLat,circular))
            {
                //目标点在该区域，如果一开始不在该区域，那么记录驶入追加一次，并且状态设置为1（进入）
                if (flag==-1){
                    inCount=inCount+1;
                }
                flag=1;
            }else {
                //目标点不在该区域，如果一开始在该区域，那么记录驶出追加一次，并且状态设置为-1（驶出）
                if (flag==1){
                    outCount=outCount+1;
                }
                flag=-1;
            }
        }

        //船舶静态信息，国家名、船舶类型、MMSI
        mmsiIOCountWithStaticInfo.setAst(analysisList.get(0).getAst());
        mmsiIOCountWithStaticInfo.setCou(analysisList.get(0).getCou());
        mmsiIOCountWithStaticInfo.setMmsi(analysisList.get(0).getMsi());
        //将该搜船的进出信息存入该对象
        mmsiIOCountWithStaticInfo.setDstSum(inCount);
        mmsiIOCountWithStaticInfo.setSrcSum(outCount);
        return mmsiIOCountWithStaticInfo;
    }

    /**
     * 对每个目标轨迹列表进行进出量分析计算（扇形）
     * @param analysisList
     * @param p
     * @return
     */
    public MmsiIOCountWithStaticInfo IOAnalysisSector(List<Analysis> analysisList, com.ict.ms.trackPlayBack.facade.common.CircularSectorWithLongitudeCrossed180 p){
        inCount=0;//流入次数
        outCount=0;//流出次数
        flag=0;//1:在区域内；2：不在区域内

        MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo=new MmsiIOCountWithStaticInfo();
        for(int i=0;i<analysisList.size();i++){
            posLon=analysisList.get(i).getLo();
            posLat=analysisList.get(i).getLa();
            //对其他每个点进行判断是否在指定区域内
            if(com.ict.ms.trackPlayBack.facade.common.IFInArea.ifInSectorCircular(posLon,posLat,p))
            {
                //目标点在该区域，如果一开始不在该区域，那么记录驶入追加一次，并且状态设置为1（进入）
                if (flag==-1){
                    inCount=inCount+1;
                }
                flag=1;
            }else {
                //目标点不在该区域，如果一开始在该区域，那么记录驶出追加一次，并且状态设置为-1（驶出）
                if (flag==1){
                    outCount=outCount+1;
                }
                flag=-1;
            }
        }

        //船舶静态信息，国家名、船舶类型、MMSI
        mmsiIOCountWithStaticInfo.setAst(analysisList.get(0).getAst());
        mmsiIOCountWithStaticInfo.setCou(analysisList.get(0).getCou());
        mmsiIOCountWithStaticInfo.setMmsi(analysisList.get(0).getMsi());
        //将该搜船的进出信息存入该对象
        mmsiIOCountWithStaticInfo.setDstSum(inCount);
        mmsiIOCountWithStaticInfo.setSrcSum(outCount);
        return mmsiIOCountWithStaticInfo;
    }

    /**
     * 对每个目标轨迹列表进行进出量分析计算（扇环形）
     * @param analysisList
     * @param p
     * @return
     */
    public MmsiIOCountWithStaticInfo IOAnalysisSectorAnnular(List<Analysis> analysisList, com.ict.ms.trackPlayBack.facade.common.AnnularSectorWithLongitudeCrossed180 p) {
        inCount = 0;//流入次数
        outCount = 0;//流出次数
        flag = 0;//1:在区域内；2：不在区域内

        MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo = new MmsiIOCountWithStaticInfo();
        for (int i = 0; i < analysisList.size(); i++) {
            posLon = analysisList.get(i).getLo();
            posLat = analysisList.get(i).getLa();
            //对其他每个点进行判断是否在指定区域内
            if (com.ict.ms.trackPlayBack.facade.common.IFInArea.ifInSectorAnnular(posLon, posLat, p)) {
                //目标点在该区域，如果一开始不在该区域，那么记录驶入追加一次，并且状态设置为1（进入）
                if (flag == -1) {
                    inCount = inCount + 1;
                }
                flag = 1;
            } else {
                //目标点不在该区域，如果一开始在该区域，那么记录驶出追加一次，并且状态设置为-1（驶出）
                if (flag == 1) {
                    outCount = outCount + 1;
                }
                flag = -1;
            }
        }

        //船舶静态信息，国家名、船舶类型、MMSI
        mmsiIOCountWithStaticInfo.setAst(analysisList.get(0).getAst());
        mmsiIOCountWithStaticInfo.setCou(analysisList.get(0).getCou());
        mmsiIOCountWithStaticInfo.setMmsi(analysisList.get(0).getMsi());
        //将该搜船的进出信息存入该对象
        mmsiIOCountWithStaticInfo.setDstSum(inCount);
        mmsiIOCountWithStaticInfo.setSrcSum(outCount);
        return mmsiIOCountWithStaticInfo;
    }
    /**
     * 对每个目标轨迹列表进行进出量分析计算（多边形）
     * @param analysisList
     * @param p
     * @return
     */
    public MmsiIOCountWithStaticInfo IOAnalysisPolygons(List<Analysis> analysisList, com.ict.ms.trackPlayBack.facade.common.PolygonWithLongitudeCrossed180 p){
        inCount=0;//流入次数
        outCount=0;//流出次数
        flag=0;//1:在区域内；2：不在区域内

        MmsiIOCountWithStaticInfo mmsiIOCountWithStaticInfo=new MmsiIOCountWithStaticInfo();
        for(int i=0;i<analysisList.size();i++){
            posLon=analysisList.get(i).getLo();
            posLat=analysisList.get(i).getLa();
            //对其他每个点进行判断是否在指定区域内
            if(com.ict.ms.trackPlayBack.facade.common.IFInArea.ifInPolygons(posLon,posLat,p))
            {
                //目标点在该区域，如果一开始不在该区域，那么记录驶入追加一次，并且状态设置为1（进入）
                if (flag==-1){
                    inCount=inCount+1;
                }
                flag=1;
            }else {
                //目标点不在该区域，如果一开始在该区域，那么记录驶出追加一次，并且状态设置为-1（驶出）
                if (flag==1){
                    outCount=outCount+1;
                }
                flag=-1;
            }
        }

        //船舶静态信息，国家名、船舶类型、MMSI
        mmsiIOCountWithStaticInfo.setAst(analysisList.get(0).getAst());
        mmsiIOCountWithStaticInfo.setCou(analysisList.get(0).getCou());
        mmsiIOCountWithStaticInfo.setMmsi(analysisList.get(0).getMsi());
        //将该搜船的进出信息存入该对象
        mmsiIOCountWithStaticInfo.setDstSum(inCount);
        mmsiIOCountWithStaticInfo.setSrcSum(outCount);
        return mmsiIOCountWithStaticInfo;
    }

    /**
     * 对目标进行目标列表分类，一个目标一个List
     * @param map 存储各个目标轨迹列表的Map，以目标ID为Key，目标列表为Value
     * @param key 目标id
     * @param analysis 目标对象信息，包括船舶经度、纬度、船舶类型，国别、ID号等
     */
    public void putAddAnalysis(Map<String,ArrayList<Analysis>> map, String key, Analysis analysis){
        if(!map.containsKey(key)){
            map.put(key, new ArrayList<Analysis>());
        }
        map.get(key).add(analysis);
    }

    public void putOrigAddAnalysis(Map<String,ArrayList<Analysis>> map, String key, Analysis analysis){
        key=key+"_"+analysis.getTp()+"_"+analysis.getSo();
        if(!map.containsKey(key)){
            map.put(key, new ArrayList<Analysis>());
        }
        map.get(key).add(analysis);
    }

    /**
     * AIS船舶类型需要经过处理才好在程序里面进行判断
     *货船 ：70-79
     油轮： 80-89
     拖船 ：31-32
     拖轮 ：52
     搜救船 ：51
     客船 ：60-69
     渔船：30
     军事船：34
     * @param shipType
     * @return
     */
    public int DealAisShipType(int shipType){
        if(shipType>70&&shipType<80){
            return 70;
        }else if(shipType>80&&shipType<90){
            return 80;
        }else if(shipType>60&&shipType<70){
            return 60;
        }else if(shipType==32){
            return 31;
        }
        else{
            return shipType;
        }
    }
}